package main

import (
	"bufio"
	"fmt"
	"io"
	"strings"
)

// 这里是说，我们有一个type，它的名字叫做intGen，它的具体类型是fun() int
type intGen func() int

/**
求斐波那契数列  1 1 2 3 5 8 13
*/
func feibonacci() intGen {
	a, b := 0, 1
	return func() int {
		a, b = b, a+b
		return a
	}
}

// 给函数实现接口
func (g intGen) Read(p []byte) (n int, err error) {
	next := g()
	if next > 10000 {
		return 0, io.EOF
	}
	// 是把格式化字符串输出到指定的字符串中，可以用一个变量来接受，然后在打印
	s := fmt.Sprintf("%d\n", next)
	return strings.NewReader(s).Read(p)
}

// 实现Reader接口
func printFileContents(reader io.Reader) {
	scanner := bufio.NewScanner(reader)
	for scanner.Scan() {
		fmt.Println(scanner.Text())
	}
}

func main() {
	f := feibonacci()
	// main.intGen1
	fmt.Printf("%T", f)
	//for i := 0; i < 10; i++ {
	//	fmt.Println(f())
	//}
	printFileContents(f)
}

/**
总结：这里的调用关系不是很了解，接下来的术语都是咔咔自己理解的，如果有大佬路过可以跟指正一下。
首先这段代码会执行printFileContents(f)，又因为f就是feibonacci()这个函数，所以
第一步执行的是feibonacci()这个函数
第二步去执行printFileContents()这个方法
第三步因为我们设置了type intGen func() int
所以会去执行Read()这个接口，咔咔认为printFileContents这个方法引入了Reader接口，然后用声明的intGen这个类型进行调用接口
暂时咔咔的理解就是这个样子，如果后期发现不对的时候在回来改，或者等大佬来给说明
*/
